package ext.tianma.project.listener;

import java.io.Serializable;
import java.util.Iterator;

import wt.events.KeyedEvent;
import wt.events.KeyedEventListener;
import wt.fc.ObjectIdentifier;
import wt.fc.ObjectReference;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceManagerEvent;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.fc.collections.WTCollection;
import wt.projmgmt.admin.Project2;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.services.ManagerException;
import wt.services.ServiceEventListenerAdapter;
import wt.services.StandardManager;
import wt.session.SessionServerHelper;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.vc.VersionReference;

import com.ptc.projectmanagement.assignment.AssignmentHelper;
import com.ptc.projectmanagement.cost.CostHelper;
import com.ptc.projectmanagement.deliverable.PlanDeliverable;
import com.ptc.projectmanagement.deliverable.PlanDeliverableLink;
import com.ptc.projectmanagement.plan.Duration;
import com.ptc.projectmanagement.plan.HealthStatusType;
import com.ptc.projectmanagement.plan.Plan;
import com.ptc.projectmanagement.plan.PlanActivity;
import com.ptc.projectmanagement.plan.Plannable;
import com.ptc.projectmanagement.plannable.PlannableHelper;

//import ext.generic.util.ObjectCloneBuilder;

public class CusProjectListenerService extends StandardManager implements PDMProjectListenerService,Serializable{
	
	private static final long serialVersionUID = -1979670257204652265L;
	
	private static final String CLASSNAME = CusProjectListenerService.class.getName();
	
	private static KeyedEventListener listener = null ;
	
	public static CusProjectListenerService newCusProjectListenerService() throws WTException{
		CusProjectListenerService instance = new CusProjectListenerService();
		
		instance.initialize();
		
		return instance;
	}

	@Override
	public String getConceptualClassname() {
		return CLASSNAME;
	}

	/**
	 * 监听事件：保存和修改
	 */
	@Override
	protected void performStartupProcess() throws ManagerException {
		listener = new WCListenerEventListener(this.getConceptualClassname());
	
		getManagerService().addEventListener( listener, PersistenceManagerEvent.generateEventKey(PersistenceManagerEvent.POST_MODIFY));
	}
	
	/**
	 * 定义内部类，用来处理相应的事件
	 * @author KWang
	 *
	 */
	class WCListenerEventListener extends ServiceEventListenerAdapter{

		private String post_modify = PersistenceManagerEvent.POST_MODIFY;
		
		public WCListenerEventListener( String manager_name ) {
			super(manager_name);			
		}
		
		public void notifyVetoableEvent( Object eve ){
			
			//获取当前事件监控的对象
			KeyedEvent keyedEvent = ( KeyedEvent )eve;
			//获取当前被监控的对象
			Object targetObj = keyedEvent.getEventTarget();
			
			//获取监控事件
			String eventType = keyedEvent.getEventType();
			
			//开起权限
			boolean flag = SessionServerHelper.manager.setAccessEnforced(false);

			try {
				
				synchronizedToProject( targetObj , eventType );
				
			} catch (WTPropertyVetoException e) {
				e.printStackTrace();
			} catch (WTException e) {
				e.printStackTrace();
			}finally{	
				SessionServerHelper.manager.setAccessEnforced(flag);
			}
		}
				

		private void synchronizedToProject(Object targetObj, String eventType) throws WTException, WTPropertyVetoException {
			
			if( targetObj == null || eventType == null || eventType.trim().isEmpty() ){
				return;
			}
			
			if( eventType.equals( post_modify ) ){
				
				if( targetObj instanceof PlanActivity ){
					
					PlanActivity sonPlanActivity = ( PlanActivity )targetObj;
					
					if( sonPlanActivity.isMilestone() ){
						return;
					}
					
					Double complete = sonPlanActivity.getPercentWorkComplete();
					//当活动不为里程碑并且完成度为百分百的时候开始同步
					if( complete == 100 ){
						System.out.println( "Debug   start ... " + CLASSNAME + "监听..." );
						
						synchronizedToProject( sonPlanActivity );
					}				
				}				
			}			
		}

		private void synchronizedToProject( PlanActivity sonPlanActivity ) throws WTException, WTPropertyVetoException {
			
			if( sonPlanActivity == null ){
				return;
			}
			
			String sonName = sonPlanActivity.getName().trim();
			
			//根据活动获取项目				
			Project2 sonProject = ( Project2 )sonPlanActivity.getContainer();

			if( sonName.contains( ">" ) ){
					
				synchronizedToProject( sonPlanActivity , sonProject );
			}else{
				//通过活动获取汇总活动，当没有汇总活动的时候则获取到的是计划
				Plannable sonPlan = sonPlanActivity.getParentPlannable();
				
				if( sonPlan instanceof Plan ){
					synchronizedToProject( sonPlanActivity , sonProject );
				}else{
					synchronizedToProject( sonPlan , sonProject );
				}
			}						
		}
		
		/**
		 * 不存在活动汇总
		 * @param sonPlanActivity
		 * @param sonProject
		 * @throws WTException 
		 * @throws WTPropertyVetoException 
		 */
		private void synchronizedToProject( PlanActivity sonPlanActivity , Project2 sonProject ) throws WTException, WTPropertyVetoException {
			if( sonPlanActivity == null || sonProject == null ){
				return;
			}
	
			//根据子活动和子项目来获取主项目中对应的主活动
			PlanActivity parentPlan = getPlanActivity( sonPlanActivity , sonProject );				
			if( parentPlan != null ){
				System.out.println( "Debug   sonPlan :" + sonPlanActivity.getName() + "... parentPlan :" + parentPlan.getName() );						
				creatOrUpdateToPD( sonPlanActivity , parentPlan );
				
				setParetnPlanActivity( sonPlanActivity , parentPlan );
			}																				
		}
		
		/**
		 * 存在活动汇总
		 * @param sonPlan
		 * @param sonProject
		 * @throws WTException 
		 * @throws WTPropertyVetoException 
		 */
		private void synchronizedToProject( Plannable sonPlan , Project2 sonProject ) throws WTException, WTPropertyVetoException {
			
			if( sonPlan == null || sonProject == null ){
				return;
			}
			
			PlanActivity sonPlanActivity = ( PlanActivity )sonPlan;
			
			if( sonPlanActivity.getPercentWorkComplete() == 100 ){
								
				//根据子活动和子项目来获取主项目中对应的主活动
				PlanActivity parentPlan = getPlanActivity( sonPlanActivity , sonProject );			
				if( parentPlan != null ){
					System.out.println( "Debug   sonPlan :" +sonPlan.getName() + "... parentPlan :" + parentPlan.getName() );		
					creatOrUpdateToPD( sonPlan , parentPlan );
					
					setParetnPlanActivity( sonPlanActivity , parentPlan );
				}								
			}										
		}
		
		/**
		 * 根据子活动和子项目来获取主项目中对应的主活动
		 * @param sonPlanActivity
		 * @param sonProject
		 * @return
		 * @throws WTException
		 */
		private PlanActivity getPlanActivity( PlanActivity sonPlanActivity , Project2 sonProject ) throws WTException{
			PlanActivity parentPlanActivity = null;
			
			if( sonPlanActivity == null || sonProject == null ){
				return parentPlanActivity;
			}
			
			String sonName = sonProject.getName();
				
			if( sonName != null && !sonName.trim().isEmpty() ){
					
				String[] strName = sonName.split("_");
					
				if( strName != null && strName.length != 1 ){
						
					String parentName = strName[0];
					System.out.println( "Debug   主活动名称："+ parentName );
					if( parentName != null && !parentName.trim().isEmpty() ){
							
						Project2 parentProject = getProject2ByName( parentName );
						
						if( parentProject != null ){								
							//根据子活动来获取主项目中的对应活动
							parentPlanActivity = querySeekPlanActivity( sonPlanActivity , parentProject );
																							
						}else{
							System.out.println( "项目为null" );
						}							
					}
				}					
			}
			return parentPlanActivity;
		}
		
		/**
		 * 复制子活动中的可交付结果到主活动上
		 * @param sonPlan
		 * @param parentPlan
		 * @throws WTException 
		 * @throws WTPropertyVetoException 
		 */
		private void creatOrUpdateToPD( Plannable sonPlan , PlanActivity parentPlan ) throws WTException, WTPropertyVetoException {
			
			if( sonPlan == null || parentPlan == null ){
				return;
			}
			
			//根据汇总活动获取子活动
			WTCollection sonCollection = PlannableHelper.service.getAllChildren( sonPlan );
			
			if( sonCollection != null ){
				
				Iterator iterator = sonCollection.iterator();

				while( iterator.hasNext() ){
					Object object = iterator.next();

					if( object instanceof ObjectReference ){
						ObjectReference orf = ( ObjectReference )object;
						object = orf.getObject();
					}
					
					if( object instanceof PlanActivity ){
						
						PlanActivity sonPlanActivity = ( PlanActivity )object;
						//判断活动是否为里程碑
						if( !sonPlanActivity.isMilestone() ){	
							creatOrUpdateToPD( sonPlanActivity , parentPlan );
						}
					}
				}
			}
			
		}
		
		/**
		 * 创建或更新任务的可交付结果
		 * @param sonPlanActivity
		 * @param parentPlan
		 * @throws WTException
		 * @throws WTPropertyVetoException
		 */
		private void creatOrUpdateToPD( PlanActivity sonPlanActivity , PlanActivity parentPlan ) throws WTException, WTPropertyVetoException{
			
			if( sonPlanActivity == null && parentPlan == null ){
				return;
			}
			
			//通过子活动获取所有的子活动中的PlanDeliverableLink
			WTCollection sonWTCollection = PlannableHelper.service.getPlanDeliverableLinks( sonPlanActivity );	
					
			//通过主活动获取所有的主活动中的PlanDeliverableLink
			WTCollection parentWTCollection = PlannableHelper.service.getPlanDeliverableLinks( parentPlan );
			
			if( parentWTCollection == null || parentWTCollection.size() == 0 ){
				
				createToPlanDeliverable( parentPlan , sonWTCollection );	
				
			}else{
				
				creatOrUpdateToPD( parentPlan , sonWTCollection , parentWTCollection );
				
			}
			
		}
		
		/**
		 * 根据子活动的可交付结果来更新主活动
		 * @param parentPlan
		 * @param sonWTCollection
		 * @param parentWTCollection
		 * @throws WTException
		 * @throws WTPropertyVetoException
		 */
		private void creatOrUpdateToPD( PlanActivity parentPlan , WTCollection sonWTCollection , WTCollection parentWTCollection ) throws WTException, WTPropertyVetoException {
			if( parentPlan == null || sonWTCollection == null || parentPlan == null ){
				return;
			}
			
			Iterator sonIterator = sonWTCollection.iterator();
			//遍历子活动中所有的可交付结果
			while( sonIterator.hasNext() ){
				Object object = sonIterator.next();
				
				if( object != null ){
					
					if( object instanceof ObjectReference ){						
						ObjectReference orf = ( ObjectReference )object;
						object = orf.getObject();
					}
					
					if( object instanceof PlanDeliverableLink ){
						PlanDeliverableLink pdLink = ( PlanDeliverableLink )object;
						
						PlanDeliverable sonPlanDeliverable = pdLink.getPlanDeliverable();
						
						if( sonPlanDeliverable != null ){
							
							boolean isExist = false;
							
							Iterator paretnIterator =  parentWTCollection.iterator();
							
							PlanDeliverable parentPlanDeliverable = null;
							//遍历主活动中所有的可交付结果
							while( paretnIterator.hasNext() ){
								Object parentObject = paretnIterator.next();
								
								if( parentObject != null ){
									
									if( parentObject instanceof ObjectReference ){						
										ObjectReference parentOrf = ( ObjectReference )parentObject;
										parentObject = parentOrf.getObject();
									}
									
									if( parentObject instanceof PlanDeliverableLink ){
										PlanDeliverableLink parentPDLink = ( PlanDeliverableLink )parentObject;
										
										parentPlanDeliverable = parentPDLink.getPlanDeliverable();
										
										isExist = checkToPlanDeliverable( sonPlanDeliverable , parentPlanDeliverable );
										
										if( isExist ){
											break;
										}
									}
								}
							}
							
							if( !isExist ){
								createToPlanDeliverable( sonPlanDeliverable , parentPlan );
							}else{
								updateToPlanDeliverable( sonPlanDeliverable ,  parentPlanDeliverable );
							}
						}						
					}
				}
			}				
		}
		
		/**
		 * 根据子活动中的可交付结果来更新主活动的可交付结果
		 * @param sonPlanDeliverable
		 * @param parentPlanDeliverable
		 * @throws WTPropertyVetoException
		 * @throws WTException
		 */
		private void updateToPlanDeliverable( PlanDeliverable sonPlanDeliverable , PlanDeliverable parentPlanDeliverable ) throws WTPropertyVetoException, WTException {
			if( sonPlanDeliverable == null || parentPlanDeliverable == null ){
				return;
			}
			//主题
			VersionReference versionReference = sonPlanDeliverable.getSubject();
			//完成百分比
			double complete = sonPlanDeliverable.getPercentComplete();
			
			if( versionReference != null ){
				parentPlanDeliverable.setSubject( versionReference );
			}
			
			parentPlanDeliverable.setPercentComplete( complete );
						
			PersistenceHelper.manager.save( parentPlanDeliverable );
		}

		/**
		 * 判断可交付结果的名称是否相同
		 * @param sonPlanDeliverable
		 * @param parentPlanDeliverable
		 * @return
		 */
		private boolean checkToPlanDeliverable( PlanDeliverable sonPlanDeliverable , PlanDeliverable parentPlanDeliverable ) {		
			boolean isExist = false;
			
			if( sonPlanDeliverable == null || parentPlanDeliverable == null ){
				return isExist;
			}
			
			if( parentPlanDeliverable.getName().trim().equals( sonPlanDeliverable.getName().trim() ) ){
				isExist = true;
			}

			return isExist;
		}

		/**
		 * 根据子活动中的可交付结果来创建主活动的可交付结果
		 * @param parentPlan
		 * @param sonWTCollection
		 * @throws WTException
		 */
		private void createToPlanDeliverable( PlanActivity parentPlan , WTCollection sonWTCollection ) throws WTException {
			if( parentPlan == null || sonWTCollection == null || sonWTCollection.size() == 0 ){
				return;
			}
			
			Iterator iterator = sonWTCollection.iterator();
			
			while( iterator.hasNext() ){
				Object object = iterator.next();
				
				if( object != null ){
					
					if( object instanceof ObjectReference ){						
						ObjectReference orf = ( ObjectReference )object;
						object = orf.getObject();
					}
					
					if( object instanceof PlanDeliverableLink ){
						PlanDeliverableLink pdLink = ( PlanDeliverableLink )object;
						
						PlanDeliverable sonPlanDeliverable = pdLink.getPlanDeliverable();
						
						if( sonPlanDeliverable != null ){
							
							createToPlanDeliverable( sonPlanDeliverable, parentPlan );
						}
					}
				}
			}			
		}
		
		/**
		 * 根据子活动中的可交付结果来创建主活动的可交付结果
		 * @param sonPlanDeliverable
		 * @param parentPlan
		 * @throws WTException
		 */
		private void createToPlanDeliverable( PlanDeliverable sonPlanDeliverable , PlanActivity parentPlan ) throws WTException {
			if( sonPlanDeliverable == null ||  parentPlan == null ){
				return;
			}
			
			//编译不通过，已丢失历史源码，于2018-10-18注释掉  by XXX
			/*PlanDeliverable clonePlanD = ( PlanDeliverable )ObjectCloneBuilder.cloneObject( sonPlanDeliverable );
			
			if( clonePlanD != null ){
				
				PlanDeliverableLink planLink =  PlanDeliverableLink.newPlanDeliverableLink( parentPlan , clonePlanD );
				
				PersistenceHelper.manager.store( planLink );	
				
			}*/
			
		}

		/**
		 * 根据子任务来设置主任务的属性并且更新主任务的上级
		 * @param sonPlanActivity
		 * @param parentPlan
		 * @throws WTPropertyVetoException 
		 * @throws WTException 
		 */
		private void setParetnPlanActivity( PlanActivity sonPlanActivity , PlanActivity parentPlan ) throws WTPropertyVetoException, WTException {
			if( sonPlanActivity == null || parentPlan == null ){
				return;
			}
			//实际工时
			Duration duration = parentPlan.getDuration();
			System.out.println( "Debug   duration ... : " + duration );
			if( duration != null )
				parentPlan.setDoneEffort( duration );
			
			
			//设置主任务的状况
			parentPlan.setHealthStatusType( HealthStatusType.GREEN );
			
			//parentPlan = (PlanActivity) ProcessorUtils.setActualAndRemainingEffortFromPercentComplete( parentPlan , 2 );
			//通过实际工时来计算完成百分比
			parentPlan = (PlanActivity) AssignmentHelper.service.calculatePercentWorkComplete( parentPlan );

			parentPlan = (PlanActivity)PersistenceHelper.manager.save( parentPlan );
			
			if( parentPlan.getDoneEffort() != null)
				AssignmentHelper.service.distributeActualWork(parentPlan);
			
			parentPlan = (PlanActivity)AssignmentHelper.service.rollUpEffort(parentPlan);
			PlannableHelper.service.propagateSchedule( ( Plannable )parentPlan.getRoot() );
			CostHelper.service.rollUpCost( parentPlan );

		}	

		/**
		 * 根据当前活动来获取指定项目中相同的活动
		 * @param planActivity   （指定需要查找的活动）
		 * @param parentProject2
		 * @return
		 * @throws WTException
		 */
		public PlanActivity querySeekPlanActivity( PlanActivity planActivity , Project2 parentProject2 ) throws WTException{
			PlanActivity planAT = null;
			//根据项目获取对应的项目中所有的活动
			QueryResult qry = getPlanActivityByProject( parentProject2 );
			
			boolean isExist = false;
			
			while( qry.hasMoreElements() ){
				Object object = qry.nextElement();
				
				if( object != null && object instanceof PlanActivity ){
					planAT = ( PlanActivity )object;
					System.out.println( "Debug   planAT.getName():"+planAT.getName()+"...planActivity.getName():"+planActivity.getName() );
					if( planAT.getName().trim().equals( planActivity.getName().trim() ) ){
						isExist = true;
						break;
					}
				}
			}
			
			if( isExist == false ){
				planAT = null;
			}
			return planAT;
		}

		/**
		 * 通过名称来获取项目
		 * @param name
		 * @return
		 * @throws WTException
		 */
		public Project2 getProject2ByName(String name) throws WTException{
			Project2 project=null;
			QuerySpec qs=null;
			QueryResult qr=null;
			qs= new QuerySpec( Project2.class );
			//根据名称查找项目
			SearchCondition sc = new SearchCondition(Project2.class, Project2.NAME, SearchCondition.EQUAL, name);		     
			qs.appendSearchCondition(sc);		    			
			qr= PersistenceHelper.manager.find(qs);
			if(qr.hasMoreElements()){
				project=(Project2)qr.nextElement();				
			}
			return project;
			
		}
		
		/**
	     * 根据项目获取对应的项目任务
	     */
	    public QueryResult getPlanActivityByProject( Project2 project) throws WTException {
			QuerySpec qs = null;
			QueryResult qr = null;
			qs = new QuerySpec(PlanActivity.class);
			ReferenceFactory rf = new ReferenceFactory();
			ObjectIdentifier objId = ObjectIdentifier.newObjectIdentifier(rf.getReferenceString(project));
			SearchCondition sc = new SearchCondition(PlanActivity.class, "containerReference.key", SearchCondition.EQUAL, objId);
			qs.appendSearchCondition(sc);
			qs.appendOrderBy(PlanActivity.class, PlanActivity.LINE_NUMBER, false);
			qr = PersistenceHelper.manager.find(qs);
			return qr;
	    }
	}
}



